package com.ygqh.baby.service.task.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.model.YgCardCouponInfo;
import com.ygqh.baby.model.YgCouponModel;
import com.ygqh.baby.model.YgCouponPageModel;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.task.YgCouponTaskService;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import com.ygqh.baby.utils.YgStringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class YgCouponTaskServiceImpl implements YgCouponTaskService {
    protected final Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    private YgTaskTimeService ygTaskTimeService;
    @Autowired
    private YgOrderService ygOrderService;
    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private YgCouponDetailService ygCouponDetailService;
    @Autowired
    private YgCouponUseDetailService ygCouponUseDetailService;
    @Autowired
    private WxMpMessageService wxMpMessageService;
    @Autowired
    private YgCardCouponDetailService ygCardCouponDetailService;
    @Value("${foreveruser.coupon.batch.id}")
    private Long foreverUserCouponBatchId;
    @Autowired
    private YgCardCouponService ygCardCouponService;
    @Autowired
    private YgCouponService ygCouponService;
    @Autowired
    private WxMpAuthorityService wxMpAuthorityService;
    @Autowired
    private SmsService smsService;

    @Override
    public void giveCouponToForeverUser() {
        TaskMethod task = TaskMethod.GiveCouponToForeverUser;
        ygTaskTimeService.execute(task, task.getCode(), new YgTaskTimeTemplate() {
            @Override
            public void execute(Date endTime) {
                endTime = DateConvertUtils.addMinute(endTime, -2);
                Date startTime = DateConvertUtils.addMinute(endTime, -task.getCode());
                System.out.println("优惠券分享任务启动，开始时间：" + DateConvertUtils.formatDateTime(startTime) + ", 结束时间：" + DateConvertUtils.formatDateTime(endTime));
                // 已支付订单
                List<YgOrder> orderList = ygOrderService.findByPaidTimeHasDetail(startTime, endTime, null);
                if (CollectionUtils.isEmpty(orderList)) {
                    return;
                }
                // 排除0元订单 并以用户分组
                Map<Long, List<YgOrder>> orderMapGroupByUserId = orderList.stream().filter(o -> o.getPaidPrice().compareTo(BigDecimal.valueOf(0)) != 0)
                        .collect(Collectors.groupingBy(YgOrder::getUserId));
                if (MapUtils.isEmpty(orderMapGroupByUserId)) {
                    return;
                }
                for (Map.Entry<Long, List<YgOrder>> entry : orderMapGroupByUserId.entrySet()) {
                    Long userId = entry.getKey();
                    List<YgOrder> orderListByFilter = entry.getValue();
                    if (CollectionUtils.isEmpty(orderListByFilter)) {
                        continue;
                    }
                    List<Long> orderIdList = orderListByFilter.stream().map(YgOrder::getOrderId).collect(Collectors.toList());
                    // 获取用户第一单
                    YgOrder firstOrder = ygOrderService.findFirstOrder(userId, null);
                    if (firstOrder == null) {
                        continue;
                    }
                    if (!orderIdList.contains(firstOrder.getOrderId())) {
                        continue;
                    }
                    // 订单的来源用户分享红包被订单用户领取
                    List<YgCouponUseDetail> couponUseDetailList = ygCouponUseDetailService.findCouponUseDetailByShareUserId(userId, null);
                    if (CollectionUtils.isEmpty(couponUseDetailList)) {
                        continue;
                    }
                    handlerCouponUseDetail(firstOrder, couponUseDetailList);
                }
            }
        });
    }

    private void handlerCouponUseDetail(YgOrder firstOrder, List<YgCouponUseDetail> couponUseDetailList) {
        Long userId = firstOrder.getUserId();
        // 根据分享用户分组
        Map<Long, List<YgCouponUseDetail>> map = couponUseDetailList.stream().filter(o -> o.getShareUserId().compareTo(userId) != 0)
                .filter(o -> o.getCreateTime().compareTo(firstOrder.getPaidTime()) < 0).collect(Collectors.groupingBy(YgCouponUseDetail::getShareUserId));
        for (Map.Entry<Long, List<YgCouponUseDetail>> entry : map.entrySet()) {
            Long shareUserId = entry.getKey();
            List<YgCouponUseDetail> list = entry.getValue();
            try {
                if (CollectionUtils.isEmpty(list)) {
                    continue;
                }
                sendCoupon(firstOrder, shareUserId);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(ExceptionUtil.getExceptionMsg(e));
            }
        }
    }

    private void sendCoupon(YgOrder firstOrder, Long shareUserId) {
        YgUser shareUser = ygUserService.findById(shareUserId);
        Message message = ygCouponDetailService.receiveCouponWithRemark(foreverUserCouponBatchId, "分享新用户下单赠券：orderId-->" + firstOrder.getOrderId(), shareUser);
        if (message.getType().equals(Message.Type.success)) {
            wxMpMessageService.sendCouponMsg("恭喜您获得一张满100减20的优惠券", "/user/coupon.html", shareUser, "20元优惠券",
                    DateConvertUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"), "请到【我的】->【优惠券】界面查询\n18年新款热卖，手慢无");
        } else {
            throw new YgException("新用户下单优惠券保存结果：" + message.getType().name() + "," + message.getContent());
        }
    }

    @Override
    public void CardCouponOverdueReminding() {
        Date now = DateConvertUtils.getDateStart(new Date());
        String format_now = DateConvertUtils.format(now);
        CardType[] types = new CardType[]{CardType.BasicsGift, CardType.BirthdayGift, CardType.QueenGift, CardType.DrawPrize, CardType.OrderGift};
        String startDate = DateConvertUtils.format(DateConvertUtils.addDay(now, -7));
        String endDate = DateConvertUtils.format(DateConvertUtils.addDay(now, -6));
        List<YgCardCouponDetail> list = ygCardCouponDetailService.findCardCouponList(UseStatus.UnUsed, startDate, endDate, types);

        if (CollectionUtils.isNotEmpty(list)) {
            Map<Long, List<YgCardCouponDetail>> mapByUser = list.stream().collect(Collectors.groupingBy(YgCardCouponDetail::getUserId));
            mapByUser.forEach((K, V) -> {

                StringBuilder productNames = new StringBuilder();
                for (YgCardCouponDetail cd : V) {
                    String format = DateConvertUtils.format(DateConvertUtils.addDay(cd.getCreateTime(), 6));
                    if (format_now.equals(format)) {
                        productNames.append("【").append(cd.getProductName()).append("】,");
                    }
                }

                if (productNames.length() > 0) {
                    YgUser ygUser = ygUserService.findById(K);
                    String names = productNames.toString();
                    String title = "您的礼物" + names.substring(0, names.length() - 1) + "还没有兑换哦，购买任意商品就可把礼物一起起带回家啦，快去下单吧~~\n";
                    wxMpMessageService.sendOverdueReminder(ygUser, title, "/user/card-coupon-list.html", "\n春夏商品热销中，快去选购吧~~", "壹果商城",
                            DateConvertUtils.formatDateTime(new Date()));
                }

            });

        }

    }

    @Override
    public void giveCardCouponToOrderSource() {
        TaskMethod task = TaskMethod.GiveCardCouponToOrderSource;
        ygTaskTimeService.execute(task, task.getCode(), new YgTaskTimeTemplate() {
            @Override
            public void execute(Date endTime) {
                endTime = DateConvertUtils.addMinute(endTime, -2);
                Date startTime = DateConvertUtils.addMinute(endTime, -task.getCode());
                System.out.println("卡券分享任务启动，开始时间：" + DateConvertUtils.formatDateTime(startTime) + ", 结束时间：" + DateConvertUtils.formatDateTime(endTime));
                // 已支付订单
                List<YgOrder> orderList = ygOrderService.findOrderBySendTimeHasDetail(startTime, endTime, null);
                if (CollectionUtils.isEmpty(orderList)) {
                    return;
                }
                // 以用户分组
                Map<Long, List<YgOrder>> orderMapGroupByUserId = orderList.stream().collect(Collectors.groupingBy(YgOrder::getUserId));
                if (MapUtils.isEmpty(orderMapGroupByUserId)) {
                    return;
                }
                List<YgCardCoupon> cardsByMonth = ygCardCouponService.findCardsByMonth(CardType.PullNew, CardMode.Goods, null);
                if (CollectionUtils.isEmpty(cardsByMonth)) {
                    return;
                }
                YgCardCoupon ygCardCoupon = cardsByMonth.get(0);
                for (Map.Entry<Long, List<YgOrder>> entry : orderMapGroupByUserId.entrySet()) {
                    Long userId = entry.getKey();
                    List<YgOrder> orderListByFilter = entry.getValue();
                    if (CollectionUtils.isEmpty(orderListByFilter)) {
                        continue;
                    }
                    List<Long> orderIdList = orderListByFilter.stream().map(YgOrder::getOrderId).collect(Collectors.toList());
                    logger.info("区间内发货订单：userId-->" + userId + ";order-->" + orderIdList.toString());
                    // 获取用户第一单
                    YgOrder firstOrder = ygOrderService.findFirstSendOrder(userId, null, null);
                    if (firstOrder == null) {
                        continue;
                    }
                    logger.info("该用户发货第一单：userId-->" + userId + ";order-->" + firstOrder.getOrderId());
                    if (!orderIdList.contains(firstOrder.getOrderId())) {
                        continue;
                    }
                    // 验证用户是否参与了活动
                    List<YgCardCouponInfo> couponInfoList = ygCardCouponDetailService.findByCardIdAndUserId(ygCardCoupon.getId(), userId);
                    if (CollectionUtils.isEmpty(couponInfoList)) {
                        continue;
                    }
                    YgCardCouponInfo cardInfo = couponInfoList.get(0);
                    try {
                        System.out.println(cardInfo.toString());
                        generateCardCoupon(userId, cardInfo.getSourceCode(), ygCardCoupon);
                    } catch (Exception e) {
                        logger.error("反赠用户-->" + cardInfo.getSourceCode() + ";Exception-->" + ExceptionUtil.getExceptionMsg(e));
                        e.printStackTrace();
                    }
                }
                System.out.println("卡券分享任务结束");
            }
        });
    }

    private void generateCardCoupon(Long userId, String sourceCode, YgCardCoupon ygCardCoupon) {
        System.out.println("来源用户：" + sourceCode);
        YgUser sourceUser = ygUserService.findBySourceCode(sourceCode);
        if (sourceUser == null) {
            return;
        }
        YgUser orderUser = ygUserService.findById(userId);
        Message message = ygCardCouponDetailService.generateCardCoupon(sourceUser.getId(), ygCardCoupon, null, null, null);
        if (Message.isSuccess(message)) {
            wxMpMessageService.sendTodoTasks(sourceUser, "您的好友" + orderUser.getNickName() + "的订单发货了，送您一块保宁皂，已经放到您的卡券中", "请及时带回哦", new Date(),
                    "请点击 我的->卡券 进行查看", "/user/card-coupon-list.html?level=" + sourceUser.getLevel());
        }
    }

    @Override
    public void remindCardCouponOver() {
        Date runTime = new Date();
        try {
            // 10天后过期的未使用卡券
            String afterTen = DateConvertUtils.format(DateConvertUtils.addDay(runTime, 10));
            List<YgCardCouponDetail> cardCouponDetailListByTen = ygCardCouponDetailService
                    .findCardCouponList(null, null, UseStatus.UnUsed, null, null, afterTen);
            processCardCouponDetail(cardCouponDetailListByTen, afterTen);
            // 20天后过期的未使用卡券
            String afterTwenty = DateConvertUtils.format(DateConvertUtils.addDay(runTime, 20));
            List<YgCardCouponDetail> cardCouponDetailListByTwenty = ygCardCouponDetailService
                    .findCardCouponList(null, null, UseStatus.UnUsed, null, null, afterTwenty);
            processCardCouponDetail(cardCouponDetailListByTwenty, afterTwenty);
            ygTaskTimeService.saveOrUpdate(TaskMethod.RemindCardCouponOver.name(), runTime, "【卡券到期提醒任务】执行成功");
        } catch (Exception e) {
            e.printStackTrace();
            ygTaskTimeService.saveOrUpdate(TaskMethod.RemindCardCouponOver.name(), runTime, "【卡券到期提醒任务】执行失败。error=" + ExceptionUtil.getExceptionMsg(e));
        }
    }

    private void processCardCouponDetail(List<YgCardCouponDetail> cardCouponDetailList, String specifiedDate) {
        if (CollectionUtils.isEmpty(cardCouponDetailList)) {
            logger.info(specifiedDate + "--》无当天过期的未使用卡券");
            return;
        }
        Set<Long> userSet = cardCouponDetailList.stream().map(YgCardCouponDetail::getUserId).collect(Collectors.toSet()); // 抽取用户id
        List<YgUser> userList = ygUserService.findOpenIds(new ArrayList<>(userSet));
        if (CollectionUtils.isEmpty(userList)) {
            return;
        }
        Map<Long, List<YgCardCouponDetail>> cardCouponDetailMapGroupByUserId = cardCouponDetailList.stream().collect(Collectors.groupingBy(YgCardCouponDetail::getUserId)); // 以用户分组
        Map<Long, List<YgUser>> userMapGroupById = userList.stream().collect(Collectors.groupingBy(YgUser::getId));
        YgCouponPageModel couponPage = ygCouponService.getCouponPage();
        String msgRemark;
        if (couponPage != null && StringUtils.isNotBlank(couponPage.getTitle())) {
            msgRemark = couponPage.getTitle();
        } else {
            msgRemark = "";
        }
        for (Map.Entry<Long, List<YgCardCouponDetail>> entry : cardCouponDetailMapGroupByUserId.entrySet()) {
            if (CollectionUtils.isEmpty(userMapGroupById.get(entry.getKey()))) {
                continue;
            }
            sendOverdueRemindCardCouponMessage(userMapGroupById.get(entry.getKey()).get(0), entry.getValue(), msgRemark);
        }
    }

    private void sendOverdueRemindCardCouponMessage(YgUser user, List<YgCardCouponDetail> detailList, String msgRemark) {
        if (user == null || CollectionUtils.isEmpty(detailList)) {
            return;
        }
        StringBuilder title = new StringBuilder("您的礼物");
        for (YgCardCouponDetail cd : detailList) {
            title.append("【").append(cd.getProductName()).append("】");
        }
        title.append("还没有兑换哦，购买任意商品就可把礼物一起起带回家啦，快去下单吧~~\n");
        wxMpMessageService.sendOverdueReminder(user, title.toString(), "/user/card-coupon-list.html", msgRemark, "壹果商城",
                DateConvertUtils.formatDateTime(new Date()));
    }

    @Override
    public void remindCouponOver() {
        String methodName = "RemindCouponOver";
        Date runTime = new Date();
        try {
            // 1天后过期的未使用优惠券
            String overDate = DateConvertUtils.format(DateConvertUtils.addDay(runTime, 1));
            List<YgCouponModel> couponModelList = ygCouponDetailService.findOverListForRemind(overDate, null);
            int count = 0;
            if (CollectionUtils.isNotEmpty(couponModelList)) {
                count = sendRemindMsgBySms(couponModelList);
            }
            ygTaskTimeService.saveOrUpdate(methodName, runTime, "【优惠券到期提醒任务】执行成功，已发数：" + count);
        } catch (Exception e) {
            e.printStackTrace();
            ygTaskTimeService.saveOrUpdate(methodName, runTime,
                    "【优惠券到期提醒任务】执行失败。error=" + ExceptionUtil.getExceptionMsg(e));
        }
    }

    private int sendRemindMsgBySms(List<YgCouponModel> couponModelList) {
        Map<Long, List<YgCouponModel>> collect = couponModelList.stream()
                .filter(o -> YgStringUtils.isChinaPhoneLegal(o.getUserName()))
                .collect(Collectors.groupingBy(YgCouponModel::getUserId));
        if (MapUtils.isEmpty(collect)) {
            return 0;
        }
//		String url = wxMpAuthorityService.getShortUrl("http://m.yiigoo.com/user/coupon.html");
        String content = "亲，您的%s元优惠券即将到期，快去%s看看吧。";
        collect.forEach((userId, list) -> {
            YgCouponModel model = list.get(0);
            String msg;
            if (SalesPlatform.Yijiadian.equals(model.getSalesPlatform())) {
                msg = String.format(content,
                        model.getFaceValue().setScale(1, BigDecimal.ROUND_HALF_UP), "壹家店");
            } else {
                msg = String.format(content,
                        model.getFaceValue().setScale(1, BigDecimal.ROUND_HALF_UP), "壹果商城");
            }
            try {
                smsService.sendSms(model.getUserName(), msg);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return collect.size();
    }
}
